//Header file definition for all geometry supported by Lambda
//We use a LHS coordinate system. Hence all angles are anticlockwise
//all vertices ordering are clockwise

#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__

#define EPSILON 0.01F

#pragma once
#include "Vector.h"
#include "Ray3.h"

struct IntersectionPacket
{
	float t;		// the value of t in ray equation
	//constructor
	IntersectionPacket() { t = 10000.0f;  /*MAX OUT*/ }
};

class Shape
{
	//This class is the base class for all primitives supported by the renderer
	//all intersection functions are implemented as virtual functions
public:
	virtual bool IntersectionTest(Ray3& R, float tmin, float tmax, IntersectionPacket& pkt) = 0;
	virtual bool ShadowRayTest(Ray3& R, float tmin, float tmax) = 0;   // this function is used to check it the shadow ray intersects this object
};

//Sphere class
//Inherits from primitve class
class Sphere:public Shape
{
public:
	Vector3 center;
	float radius;

	//Constructor
	Sphere();
	Sphere(const Vector3& c, float r);

	//Functions
	bool IntersectionTest(Ray3& R, float tmin, float tmax, IntersectionPacket& pkt);
	bool ShadowRayTest(Ray3& R, float tmin, float tmax);
};

//Triangle Class
//Primitive for most objects
class Triangle:public Shape
{
private:
	Vector3 v0, v1, v2;
	Vector3 normal;
public:
	//constructor
	Triangle();
	Triangle(const Vector3& _v0, const Vector3& _v1, const Vector3& _v2);

	//Intersection Tests
	bool IntersectionTest(Ray3& R, float tmin, float tmax, IntersectionPacket& pkt);
	bool ShadowRayTest(Ray3& R, float tmin, float tmax);

};

/*
Class: TriangleVNT
Desc: This class is similiar to the triangle class but is different in the data it encapsulates. 
	  This triangle has vertex coords, per vertex normal coords and per vertex texture coords.
	  It is a subclass of the Triangle class
*/
class TriangleVNT:public Triangle
{
private:
	// private data members
	Vector3 v0, v1, v2;		// Vertex coords
	Vector3 n0, n1, n2;		// Per vertex normal coords
	Vector3 t0, t1, t2;		// Per vertex texture coords

public:
	// constructor
	// Default constructor
	TriangleVNT();
	
	// Explicit initialization of all components
	TriangleVNT(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 n0, Vector3 n1, Vector3 n2, Vector3 t0, Vector3 t1, Vector3 t2);
};


//Quad Class
//Another normal polygonal primitive
class  Quad:public Shape
{
public:
	Vector3 v0, v1, v2, v3;		//we have for vectors


};

/*
Class: Plane
Parent Class: Shape
Desc: 3dimensional plane in implicit notation (using point and normal form)
*/
class Plane:public Shape
{
private:
public:
	// Plane is represented by a point and normal form
	Vector3 point;
	Vector3 normal;
	float d;		// distance of plane from origin (n.p = d) form
	// Constructor

	// Default constructore
	Plane(){}

	// Explicit initialization of plane 
	Plane(Vector3& point, Vector3& normal);

	// Three point initialization of plane
	Plane(Vector3& v1, Vector3& v2, Vector3& v3);

	// Functions
	
	// This function computes the the distance of the plane from the ray origin and can be used to find the point of intersection
	bool IntersectionTest(Ray3& R, float tmin, float tmax, IntersectionPacket& pkt);

	bool ShadowRayTest(Ray3& R, float tmin, float tmax){ return true;}
};


#endif